package beanstao.util.store.presenter;

import java.util.ArrayList;
import java.util.Date;

import beanstao.util.Dates;
import beanstao.util.Sber;
import beanstao.util.collections.Pair;
import beanstao.util.json.JsonLib;
import beanstao.util.log.ILog;
import beanstao.util.log.LogHelper;
import beanstao.util.store.IQD;
import beanstao.util.store.dal.DbDal;
import beanstao.util.store.database.Columns;
import beanstao.util.store.database.Where;
import beanstao.util.store.domainobject.Domain;
import beanstao.util.store.domainobject.DomainList;

import com.google.common.base.Strings;

/**
 * 一个领域对象的调度器
 * 
 * @author beanstao@google.com 
 */
public abstract class AbstractPresenter implements ILog
{
	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected <T extends Domain> String dbAllForPage(final IQD data, DbDal dal)
	{
		// 创建sqlselectcolumn
		Columns sqlList = Columns.ME_ALL();

		// 添加Where条件
		Where where = data.toSimpleWhere();

		this.orderby(data, where);

		this.groupby(data, where);

		Pair<Integer, Integer> pair = this.limit(data);

		DomainList<Domain> domainList = dal.select(sqlList, where, pair.getLeft(), pair.getRight());

		DomainList<Domain> dList = new DomainList<Domain>();
		for (Domain domain : domainList)
		{
			// System.out.println("AbstractPresenter.dbAllForPage()" + domain.get("operationid").toString());
			if (!Strings.isNullOrEmpty(domain.get("operationid").toString()))
				dList.add(domain);
		}

		if (data.getQueryType().equals("CacheOfOperationFlow") || data.getQueryType().equals("OperationFlow"))
			this.addTime(dList);

		// 为Extjs的准备的分页代码
		Sber sber = Sber.ME();
		int count = dal.count(where);
		sber.surroundQuotation("totalCount").append(":").append(count).append(',');
		sber.surroundQuotation("records").append(":");

		String json = dList.toJson();
		sber.append(json);
		sber.surroundBrace();
		return sber.toString();
	}

	/**
	 * 当取当前明细时，需根据服务器时间计算每条流水的已等待时长或已办理时长
	 */
	private void addTime(DomainList<Domain> domainList)
	{
		for (Domain domain : domainList)
			// this.logDebug("处理业务流水中的已等待时长或已办理时长：" + domain.get("operationstatus"));
			if (domain.get("operationstatus").toString().equals("0"))
			{
				Date gettickettime = Dates.parse(domain.get("gettickettime").toString());
				long offset = Dates.diffMinutes(gettickettime, Dates.now());
				domain.put("currWaitTimes", Math.abs(offset));
			}
			else if (domain.get("operationstatus").toString().equals("1"))
			{
				Date gettickettime = Dates.parse(domain.get("callcustomertime").toString());
				long offset = Dates.diffMinutes(gettickettime, Dates.now());
				domain.put("currWorkTimes", Math.abs(offset));
			}
	}

	protected Pair<Integer, Integer> limit(IQD data)
	{
		// 分页
		int start = 0;
		int limit = 100;
		if (data.getKeys().contains("start"))
			start = Integer.valueOf(String.valueOf(data.get("start").$V()));
		if (data.getKeys().contains("limit"))
			limit = Integer.valueOf(String.valueOf(data.get("limit").$V()));
		return Pair.ME(start, limit);
	}

	protected void groupby(final IQD data, Where where)
	{
		// 添加分组
		if (data.getKeys().contains("groupby"))
		{
			ArrayList<String> groupbyList = JsonLib.fromStringArray(data.get("groupby").$V());
			for (String groupby : groupbyList)
				where.addGroupBy(groupby);
		}
	}

	protected void orderby(final IQD data, Where where)
	{
		// 添加orderBy排序条件
		if (data.getKeys().contains("desc"))
		{
			ArrayList<String> descList = JsonLib.fromStringArray(data.get("desc").$V());
			for (String desc : descList)
				where.desc(desc);
		}
		if (data.getKeys().contains("asc"))
		{
			ArrayList<String> ascList = JsonLib.fromStringArray(data.get("asc").$V());
			for (String asc : ascList)
				where.asc(asc);
		}
	}

	// --- ILog -------------------------------------------------

	@Override
	public void logDebug(final Object message)
	{
		LogHelper.logDebug(this, message);
	}

	@Override
	public void logDebug(final Object message, final Throwable t)
	{
		LogHelper.logDebug(this, message, t);
	}

	@Override
	public void logError(final Object message)
	{
		LogHelper.logError(this, message);
	}

	@Override
	public void logError(final Object message, final Throwable t)
	{
		LogHelper.logError(this, message, t);
	}

	@Override
	public void logInfo(final Object message)
	{
		LogHelper.logInfo(this, message);
	}

	@Override
	public void logInfo(final Object message, final Throwable t)
	{
		LogHelper.logInfo(this, message, t);
	}

	@Override
	public void logWarn(final Object message)
	{
		LogHelper.logWarn(this, message);
	}

	@Override
	public void logWarn(final Object message, final Throwable t)
	{
		LogHelper.logWarn(this, message, t);
	}

}
